package dingtalk

import (
	"fmt"
	"strconv"
	"time"
	"unsafe"

	"gitee.com/lorock/go-dingtalk-sdk/dingtalkhttplib"
	jsoniter "github.com/json-iterator/go"
	log "github.com/sirupsen/logrus"
)

// GetUserInfoByCode 扫描登陆第三方、钉钉内部登录第三方、密码登录第三方
func (c *Client) GetUserInfoByCode(code, appID, appSecret string) (u *UserinfoBycode, err error) {
	u = new(UserinfoBycode)
	var json = jsoniter.ConfigCompatibleWithStandardLibrary
	timestamp := strconv.FormatInt(time.Now().UnixNano()/1e6, 10)

	paramData := map[string]string{
		"tmp_auth_code": code,
	}
	jsonData, err := json.Marshal(paramData)
	if err != nil {
		return u, err
	}
	sign := dingtalkhttplib.UserSignatur(timestamp, appSecret)
	param := map[string]string{
		"accessKey": appID,
		"timestamp": timestamp,
		"signature": sign,
	}
	url := fmt.Sprintf("%s?%s", GetUserInfoBycode, dingtalkhttplib.URLEncode(param))
	req := dingtalkhttplib.Post(url)
	req.Body(jsonData)
	b, err := req.AsBytes()
	if err != nil {
		return u, err
	}
	str := (*string)(unsafe.Pointer(&b))
	log.Println(*str)
	err = json.Unmarshal(b, u)
	if err != nil {
		return u, err
	}
	return u, nil
}

// GetUserInfoByIn 企业内部应用免登
// @code 免登授权码，参考上述“获取免登授权码”
func (c *Client) GetUserInfoByIn(code string) (u *UserinfoByInternal, err error) {
	u = new(UserinfoByInternal)
	var json = jsoniter.ConfigCompatibleWithStandardLibrary
	accessToken, err := c.GetAccessToken()
	if err != nil {
		return u, err
	}

	url := fmt.Sprintf("%s?access_token=%s&code=%s", GetUserInfo, accessToken, code)
	if c.Debug {
		log.Println("url:", url)
	}
	var body []byte
	body, err = dingtalkhttplib.Get(url).AsBytes()
	if err != nil {
		return u, err
	}
	str := (*string)(unsafe.Pointer(&body))
	log.Println(*str)
	err = json.Unmarshal(body, &u)
	if err != nil {
		return u, err
	}
	return u, nil
}

// GetUserInfoBySso 应用管理后台免登
func (c *Client) GetUserInfoBySso(code, ssoAccessToken string) (*UserinfoBySso, error) {
	u := new(UserinfoBySso)
	var json = jsoniter.ConfigCompatibleWithStandardLibrary
	if ssoAccessToken == "" {
		accessTokenInfo, err := c.GetSsoAccessToken(code)
		if err != nil {
			return u, err
		}
		ssoAccessToken = accessTokenInfo.AccessToken
	}

	url := fmt.Sprintf("%s?access_token=%s&code=%s", SSOGetUserInfo, ssoAccessToken, code)
	if c.Debug {
		log.Println("url:", url)
	}
	var body []byte
	body, err := dingtalkhttplib.Get(url).AsBytes()
	if err != nil {
		return u, err
	}
	str := (*string)(unsafe.Pointer(&body))
	log.Println(*str)
	err = json.Unmarshal(body, &u)
	if err != nil {
		return u, err
	}
	return u, nil
}

// GetSsoAccessToken 应用管理后台免登获取AccessToken
func (c *Client) GetSsoAccessToken(code string) (*SsoAccessToken, error) {
	s := new(SsoAccessToken)
	var json = jsoniter.ConfigCompatibleWithStandardLibrary
	accessToken, err := c.GetAccessToken()
	if err != nil {
		return s, err
	}

	url := fmt.Sprintf("%s?access_token=%s&code=%s", SSOGetToken, accessToken, code)
	if c.Debug {
		log.Println("url:", url)
	}
	var body []byte
	body, err = dingtalkhttplib.Get(url).AsBytes()
	if err != nil {
		return s, err
	}
	str := (*string)(unsafe.Pointer(&body))
	log.Println(*str)
	err = json.Unmarshal(body, &s)
	if err != nil {
		return s, err
	}
	return s, nil
}
